"""
Factory functions for creating continual learning strategies.

This module provides functions to instantiate continual learning strategies
from typed configuration objects, improving type safety and reducing coupling.
"""

from typing import Optional

from ..registry import METHOD_REGISTRY
from ..config.typed_config import ContinualLearningMethodConfig, EWCConfig, ReplayConfig
from continuallearning.registry import MethodInterface
from .ewc import EWC
from .replay import ExperienceReplay


def create_continual_learning_strategy(
    config: ContinualLearningMethodConfig,
) -> Optional[MethodInterface]:
    """
    Create a continual learning strategy from configuration.

    This factory function instantiates the appropriate strategy based on the
    configuration type and parameters, using strong typing for improved safety.

    Args:
        config: Configuration for the continual learning method

    Returns:
        A continual learning strategy instance, or None if method_type is 'none'
    """
    method_type = config.method_type

    # No continual learning strategy
    if method_type == "none":
        return None

    # Check if the method is registered in the registry
    if method_type in METHOD_REGISTRY:
        # First try to create through registry for custom methods
        if method_type == "ewc" and config.ewc:
            return METHOD_REGISTRY.get("ewc")(**config.ewc.dict())
        elif method_type == "replay" and config.replay:
            return METHOD_REGISTRY.get("replay")(**config.replay.dict())
        else:
            # Fallback to empty constructor
            return METHOD_REGISTRY.get(method_type)()

    # Built-in methods
    if method_type == "ewc" and config.ewc:
        return EWC(
            regularization_weight=config.ewc.regularization_weight,
            fisher_samples=config.ewc.fisher_samples,
            fisher_alpha=config.ewc.fisher_alpha,
        )
    elif method_type == "replay" and config.replay:
        return ExperienceReplay(
            memory_size=config.replay.memory_size,
            replay_ratio=config.replay.replay_ratio,
        )

    raise ValueError(f"Unknown continual learning method type: {method_type}")


# Register built-in methods for convenience
METHOD_REGISTRY.register("ewc")(EWC)
METHOD_REGISTRY.register("replay")(ExperienceReplay)
